#if _MSC_VER
 #pragma once
#endif // _MSC_VER

#ifndef __HERZELEID_SHADERCORE_INCLUDED__
 #define __HERZELEID_SHADERCORE_INCLUDED__
 #include "HerzeleidRendererShading.hxx"
 #include "HerzeleidShaderSwapSet.hxx"
 #include "HerzeleidSwapSetArray.hxx"
 #include "HerzeleidShaderSlot.hxx"

//////////////////////////////////////////////////////////////////////////////////////////////
HerzeleidRendererShadingNamespaceBegin
	typedef HerzeleidRendererCoreNamespaceImpl::Context3 NativeImmediateContext3; TinyTypeDecl(NativeImmediateContext3);
	typedef HerzeleidRendererCoreNamespaceImpl::Context3 NativeDeferredContext3; TinyTypeDecl(NativeDeferredContext3);
	typedef HerzeleidRendererResourcesNamespaceImpl::GeometryShader NativeGeometryShader; TinyTypeDecl(NativeGeometryShader);
	typedef HerzeleidRendererResourcesNamespaceImpl::ComputeShader NativeComputeShader; TinyTypeDecl(NativeComputeShader);
	typedef HerzeleidRendererResourcesNamespaceImpl::DomainShader NativeDomainShader; TinyTypeDecl(NativeDomainShader);
	typedef HerzeleidRendererResourcesNamespaceImpl::VertexShader NativeVertexShader; TinyTypeDecl(NativeVertexShader);
	typedef HerzeleidRendererResourcesNamespaceImpl::PixelShader NativePixelShader; TinyTypeDecl(NativePixelShader);
	typedef HerzeleidRendererResourcesNamespaceImpl::HullShader NativeHullShader; TinyTypeDecl(NativeHullShader);
	TinyTypeDecl( PipelineShaderSwapSet );
	TinyTypeDecl( ComputeShaderSwapSet );
HerzeleidRendererShadingNamespaceEnd;
//////////////////////////////////////////////////////////////////////////////////////////////
HerzeleidRendererShadingNamespaceBegin template <class TNative> struct NativeShader
{
	TNative *NativeShaderPtr;

} HerzeleidRendererShadingNamespaceEnd;
//////////////////////////////////////////////////////////////////////////////////////////////
HerzeleidRendererShadingNamespaceBegin struct ShaderBase
{
	typedef ID3DBlob Blob; TinyTypeDecl(Blob); 

	ShaderBase();
	ShaderSlot eSlot;
	WRL::ComPtr<Blob> Bytecode;

} HerzeleidRendererShadingNamespaceEnd;
//////////////////////////////////////////////////////////////////////////////////////////////
HerzeleidRendererShadingNamespaceBegin struct PipelineShaderBase : 
	public ShaderBase
{
	typedef SwapSetArray<PipelineShaderSwapSet> PipelineShaderSwapSetArray;
	PipelineShaderSwapSetArray SetArray;
	PipelineShaderBase();

} HerzeleidRendererShadingNamespaceEnd;
//////////////////////////////////////////////////////////////////////////////////////////////
HerzeleidRendererShadingNamespaceBegin struct ComputeShaderBase : 
	public ShaderBase
{
	typedef SwapSetArray<ComputeShaderSwapSet> ComputeShaderSwapSetArray;
	ComputeShaderSwapSetArray SetArray;
	ComputeShaderBase();

} HerzeleidRendererShadingNamespaceEnd;
//////////////////////////////////////////////////////////////////////////////////////////////
HerzeleidRendererShadingNamespaceBegin template <class TNative> struct PipelineShader : 
	public NativeShader<TNative>,
	public PipelineShaderBase
{
	PipelineShader() : PipelineShaderBase(),  NativeShader() { }

} HerzeleidRendererShadingNamespaceEnd;
//////////////////////////////////////////////////////////////////////////////////////////////
HerzeleidRendererShadingNamespaceBegin struct CoreVertexShader : 
	public PipelineShader<NativeVertexShader>
{
	CoreVertexShader();

} HerzeleidRendererShadingNamespaceEnd;
//////////////////////////////////////////////////////////////////////////////////////////////
HerzeleidRendererShadingNamespaceBegin struct CoreHullShader : 
	public PipelineShader<NativeHullShader>
{
	CoreHullShader();

} HerzeleidRendererShadingNamespaceEnd;
//////////////////////////////////////////////////////////////////////////////////////////////
HerzeleidRendererShadingNamespaceBegin struct CoreDomainShader : 
	public PipelineShader<NativeDomainShader>
{
	CoreDomainShader();

} HerzeleidRendererShadingNamespaceEnd;
//////////////////////////////////////////////////////////////////////////////////////////////
HerzeleidRendererShadingNamespaceBegin struct CoreGeometryShader : 
	public PipelineShader<NativeGeometryShader>
{
	CoreGeometryShader();

} HerzeleidRendererShadingNamespaceEnd;
//////////////////////////////////////////////////////////////////////////////////////////////
HerzeleidRendererShadingNamespaceBegin struct CorePixelShader : 
	public PipelineShader<NativePixelShader>
{
	CorePixelShader();

} HerzeleidRendererShadingNamespaceEnd;
//////////////////////////////////////////////////////////////////////////////////////////////
HerzeleidRendererShadingNamespaceBegin struct CoreComputeShader : 
	public NativeShader<NativeComputeShader>,
	public ComputeShaderBase
{
	CoreComputeShader();

} HerzeleidRendererShadingNamespaceEnd;
//////////////////////////////////////////////////////////////////////////////////////////////
HerzeleidRendererShadingNamespaceBegin
	TinyTypeDecl( PipelineShaderBase );
	TinyTypeDecl( ComputeShaderBase );
	TinyTypeDecl( ShaderBase );
HerzeleidRendererShadingNamespaceEnd;
//////////////////////////////////////////////////////////////////////////////////////////////
HerzeleidRendererShadingNamespaceBegin
// This method assumes the pContext is not a nullptr and uSwapSlot is in range. 
HERZELEID_FORCEINLINING HERZELEID_NOALIAS Void BindStageVSDeferred( 
	_In_ NativeDeferredContext3PtrConst pContext, 
	_In_ NativeVertexShaderPtrConst pNativeShader, 
	_In_ PipelineShaderBaseConstPtrConst Core, 
	_In_opt_ UInt32 uSwapSlot = 0u 
	);
// This method assumes the pContext is not a nullptr and uSwapSlot is in range. 
HERZELEID_FORCEINLINING HERZELEID_NOALIAS Void BindStageHSDeferred( 
	_In_ NativeDeferredContext3PtrConst pContext, 
	_In_ NativeHullShaderPtrConst pNativeShader, 
	_In_ PipelineShaderBaseConstPtrConst Core, 
	_In_opt_ UInt32 uSwapSlot = 0u 
	);
// This method assumes the pContext is not a nullptr and uSwapSlot is in range. 
HERZELEID_FORCEINLINING HERZELEID_NOALIAS Void BindStageDSDeferred( 
	_In_ NativeDeferredContext3PtrConst pContext, 
	_In_ NativeDomainShaderPtrConst pNativeShader, 
	_In_ PipelineShaderBaseConstPtrConst Core, 
	_In_opt_ UInt32 uSwapSlot = 0u 
	);
// This method assumes the pContext is not a nullptr and uSwapSlot is in range. 
HERZELEID_FORCEINLINING HERZELEID_NOALIAS Void BindStageGSDeferred( 
	_In_ NativeDeferredContext3PtrConst pContext, 
	_In_ NativeGeometryShaderPtrConst pNativeShader, 
	_In_ PipelineShaderBaseConstPtrConst Core, 
	_In_opt_ UInt32 uSwapSlot = 0u 
	);
// This method assumes the pContext is not a nullptr and uSwapSlot is in range. 
HERZELEID_FORCEINLINING HERZELEID_NOALIAS Void BindStagePSDeferred( 
	_In_ NativeDeferredContext3PtrConst pContext, 
	_In_ NativePixelShaderPtrConst pNativeShader, 
	_In_ PipelineShaderBaseConstPtrConst pCore, 
	_In_opt_ UInt32 uiSwappingSlot = 0u 
	);
// This method assumes the pContext is not a nullptr and uSwapSlot is in range. 
HERZELEID_FORCEINLINING HERZELEID_NOALIAS Void BindStageCSDeferred( 
	_In_ NativeDeferredContext3PtrConst pContext, 
	_In_ NativeComputeShaderPtrConst pNativeShader,
	_In_ ComputeShaderBaseConstPtrConst Core, 
	_In_opt_ UInt32 uSwapSlot = 0u 
	);
// This method assumes the pContext is not a nullptr. 
HERZELEID_FORCEINLINING HERZELEID_NOALIAS Void UnbindStageVSDeferred( 
	_In_ NativeDeferredContext3PtrConst pContext 
	);
// This method assumes the pContext is not a nullptr. 
HERZELEID_FORCEINLINING HERZELEID_NOALIAS Void UnbindStageHSDeferred( 
	_In_ NativeDeferredContext3PtrConst pContext 
	);
// This method assumes the pContext is not a nullptr. 
HERZELEID_FORCEINLINING HERZELEID_NOALIAS Void UnbindStageDSDeferred( 
	_In_ NativeDeferredContext3PtrConst pContext 
	);
// This method assumes the pContext is not a nullptr. 
HERZELEID_FORCEINLINING HERZELEID_NOALIAS Void UnbindStageGSDeferred(
	_In_ NativeDeferredContext3PtrConst pContext 
	);
// This method assumes the pContext is not a nullptr. 
HERZELEID_FORCEINLINING HERZELEID_NOALIAS Void UnbindStagePSDeferred( 
	_In_ NativeDeferredContext3PtrConst pContext 
	);
// This method assumes the pContext is not a nullptr. 
HERZELEID_FORCEINLINING HERZELEID_NOALIAS Void UnbindStageCSDeferred( 
	_In_ NativeDeferredContext3PtrConst pContext 
	);
HerzeleidRendererShadingNamespaceEnd;
//////////////////////////////////////////////////////////////////////////////////////////////
HerzeleidRendererShadingNamespaceBegin
	TinyTypeDecl( CoreGeometryShader );
	TinyTypeDecl( CoreComputeShader );
	TinyTypeDecl( CoreDomainShader );
	TinyTypeDecl( CoreVertexShader );
	TinyTypeDecl( CorePixelShader );
	TinyTypeDecl( CoreHullShader );
HerzeleidRendererShadingNamespaceEnd;
//////////////////////////////////////////////////////////////////////////////////////////////

#endif